﻿''' <summary>
''' This class implements a directory collector.
''' </summary>
''' <remarks>
''' The purpose of the directory collector is to read information
''' of files that reside in configured directories and output the 
''' information to the system info report.
''' </remarks>
Public Class DirectoryCollector
    Implements ICollector

    ''' <summary>
    ''' List of writers passed when Startup() is called.
    ''' </summary>
    ''' <remarks></remarks>
    Protected m_writers As List(Of Writer.IWriter)

    ''' <summary>
    ''' List of directory entries.
    ''' </summary>
    ''' <remarks></remarks>
    Protected m_entries As List(Of DirectoryEntry)

    ''' <summary>
    ''' This holds an error description.
    ''' </summary>
    ''' <remarks></remarks>
    Protected m_error As String

    Public Sub Cleanup() Implements ICollector.Cleanup

        'Nothing to do

    End Sub

    Public Sub Run() Implements ICollector.Run

        'Write our category name.
        Writer.WritersHelper.WriteCategory("Directory Information", m_writers)

        'If an error occurred while reading the configuration file, write
        'it out and stop here.
        If m_error <> "" Then
            Writer.WritersHelper.WriteCategoryError(m_error, m_writers)
        Else
            'Scan all assembly entries.
            For Each dir As DirectoryEntry In m_entries
                Try
                    'Write the assembly name entry.
                    Writer.WritersHelper.WriteSection(dir.Name, m_writers)
                    'Process this path.
                    ProcessDir(dir.Path, dir.FileMask, dir.Recurse)
                Catch ex As Exception
                    'Error gathering info.
                    Writer.WritersHelper.WriteSectionError("Error retrieving directory information (" + ex.Message + ")", m_writers)
                End Try
                'Write out a blank.
                Writer.WritersHelper.WriteBlank(m_writers)
            Next
        End If

    End Sub

    Public Sub Startup(ByVal cfgFile As String, ByVal writers As System.Collections.Generic.List(Of Writer.IWriter)) Implements ICollector.Startup

        'Get all writers.
        m_writers = writers
        'Read configuration file.
        ReadConfiguration(cfgFile)

    End Sub

    ''' <summary>
    ''' Read the configuration file.
    ''' </summary>
    ''' <param name="fName">File name with directory collector configuration.</param>
    ''' <remarks></remarks>
    Protected Sub ReadConfiguration(ByVal fName As String)

        Const DIRECTORY_TABLE As String = "Directory"

        Try
            'Read in a dataset.
            Dim ds As New DataSet
            ds.ReadXml(fName)
            m_entries = New List(Of DirectoryEntry)

            'Parse all entries.
            For i As Integer = 0 To ds.Tables(DIRECTORY_TABLE).Rows.Count - 1
                With ds.Tables(DIRECTORY_TABLE).Rows(i)
                    m_entries.Add(New DirectoryEntry(Convert.ToString(.Item("Name")), _
                                                    Convert.ToString(.Item("Path")), _
                                                    Convert.ToString(.Item("FileMask")), _
                                                    Convert.ToBoolean(.Item("Recurse"))))
                End With
            Next

            ds.Dispose()
            ds = Nothing

            'Signal no error.
            m_error = ""
        Catch ex As Exception
            'Keep the error here.
            m_error = ex.ToString()
        End Try

    End Sub

    ''' <summary>
    ''' Process a directory's files.
    ''' </summary>
    ''' <param name="topDir">Directory to start from.</param>
    ''' <param name="fileMask">File mask of files to look for.</param>
    ''' <param name="recurse">Recurse flag.</param>
    ''' <remarks></remarks>
    Protected Sub ProcessDir(ByVal topDir As String, ByVal fileMask As String, ByVal recurse As Boolean)

        Dim files() As String = System.IO.Directory.GetFiles(topDir, fileMask)
        For i As Integer = 0 To files.GetUpperBound(0)
            Try
                Dim FI As New System.IO.FileInfo(files(i))
                Writer.WritersHelper.WriteEntry("File", FI.FullName, m_writers)
                Writer.WritersHelper.WriteEntry("Size", (FI.Length / 1024).ToString("N2") + "kb", m_writers)
                Writer.WritersHelper.WriteEntry("Created", FI.CreationTime.ToString(), m_writers)
                Writer.WritersHelper.WriteEntry("Written", FI.LastWriteTime.ToString(), m_writers)
            Catch ex As Exception
                Writer.WritersHelper.WriteEntryError("Error retrieving file information (" + ex.Message + ")", m_writers)
            End Try
            If i <> files.GetUpperBound(0) Then Writer.WritersHelper.WriteBlankEntry(m_writers)
        Next

        If recurse Then
            Dim dirs() As String = System.IO.Directory.GetDirectories(topDir)
            For i As Integer = 0 To dirs.GetUpperBound(0)
                ProcessDir(dirs(i), fileMask, True)
            Next
        End If

    End Sub

End Class
